/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-8-11 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-8-11		Created.
 ****************************************************************************
 **/
package com.me.client.plugins.TicTacToe;

/**
 * TicTacToe游戏逻辑. <br/>
 * 下午7:50:19 2012-8-11
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class TTTGameLogic {
	private static int SYMBOL_X = 1;
	private static int SYMBOL_O = 2;
	private static final int EMPTY = 0;
	private static int ENEMY_AI = 1;
	private boolean gameEnds = false;
	private boolean waittingForUser = true;
	private int[] gamesArea = { EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY };
	private int userPlaying = SYMBOL_X;
	private int enemyPlaying = SYMBOL_O;
	private TTTWindow myWindow = null;
	private int enemyType = 1;
	private int aiQuality = 0;
	private String[] winCombinations = { "123", "456", "789", "147", "258", "369", "159", "357" };
	public String lastWinCombi = null;

	public TTTGameLogic(TTTWindow gameWindow) {
		// TODO Auto-generated constructor stub
		this.myWindow  = gameWindow;
	}

	/**
	 * 用户下棋的操作.
	 * 
	 * @param index
	 * @return
	 */
	public boolean userAction(int index) {
		if (this.gameEnds) {
			this.setGameStatus("Start a new game first!");
			return false;
		}
		if (!this.waittingForUser) {
			this.setGameStatus("It's not yor turn! Wait for ENEMY.");
			return false;
		}
		if (this.gamesArea[index - 1] == EMPTY) {
			this.gamesArea[index - 1] = this.userPlaying;
			this.myWindow.setSymbolOnButton(index, this.userPlaying);
		} else {
			this.setGameStatus("Allready used - choose another field!");
			return false;
		}
		this.waittingForUser = false;
		if (this.checkForGameEnd()) {
			return true;
		}
		this.setGameStatus("Waiting for ENEMY...");
		if (this.enemyType == ENEMY_AI) {
			this.AITurn(false);
			if (this.checkForGameEnd()) {
				return true;
			}
		}
		return true;
	}

	private void AITurn(boolean firstTurn) {
		if (firstTurn) {
			if (this.externalAction(5)) {
				return;
			}
		}
		int sum = 0;
		int content = EMPTY;
		int empty = -1;
		if (this.aiQuality  < 2) {
			for (int i = 0; i < this.winCombinations .length; i++) {
				for (int j = 0; j < 3; j++) {
					content = this.getWinCombinationField(i, j);
					if (content == this.enemyPlaying) {
						sum++;
					}
					if (content == EMPTY) {
						empty = j;
					}
				}
				if (sum > 1 && empty >= 0) {
					if (this.externalAction(this.getWinCombinationFieldIndex(i, empty))) {
						return;
					}
				} else {
					sum = 0;
					empty = -1;
				}
			}
		}

		sum = 0;
		content = EMPTY;
		empty = -1;
		for (int i = 0; i < this.winCombinations.length; i++) {
			for (int j = 0; j < 3; j++) {
				content = this.getWinCombinationField(i, j);
				if (content == this.userPlaying) {
					sum++;
				}
				if (content == EMPTY) {
					empty = j;
				}
			}
			if (sum > 1 && empty >= 0) {
				// We must block!
				if (this.externalAction(this.getWinCombinationFieldIndex(i, empty))) {
					return;
				}
			} else {
				sum = 0;
				empty = -1;
			}
		}

		if (this.aiQuality == 0) {
			sum = 0;
			content = EMPTY;
			empty = -1;
			for (int i = 0; i < this.winCombinations.length; i++) {
				for (int j = 0; j < 3; j++) {
					content = this.getWinCombinationField(i, j);
					if (content == this.enemyPlaying)
						sum++;
					if (content == EMPTY)
						empty = j;
					if (content == this.userPlaying)
						sum--;
				}
				if (sum > 0 && empty >= 0) {
					// Use a free possible combination
					if (this.externalAction(this.getWinCombinationFieldIndex(i, empty))) {
						return;
					}
				} else {
					sum = 0;
					empty = -1;
				}
			}
		}

		// Still no good turn - use the middle field
		if (this.gamesArea[4] == EMPTY) {
			this.externalAction(4 + 1);
			return;
		}

		// Find next free field
		for (int k = 0; k < this.gamesArea.length; k++) {
			if (this.gamesArea[k] == EMPTY) {
				System.out.println("AI has no better idea than using the next free field.");
				this.externalAction(k + 1);
				return;
			}
		}
		
	}

	public boolean externalAction(int index) {
		if(this.waittingForUser){
			return false;
		}
		if(this.gamesArea[index - 1] == EMPTY){
			this.gamesArea[index - 1] = this.enemyPlaying;
			this.myWindow.setSymbolOnButton(index, this.enemyPlaying);
			this.waittingForUser = true;
			if(this.checkForGameEnd()){
				return true;
			}
			this.setGameStatus("Waiting for YOU...");
			return true;
		}
		return false;
	}

	/**
	 * 获取方格的索引号.1.2.3.4.5..9.
	 * @param combi
	 * @param field
	 * @return
	 */
	private int getWinCombinationFieldIndex(int combi, int field) {
		return Integer.parseInt(this.winCombinations[combi].substring(field, field + 1));
	}

	/**
	 * 获取方格内的值,Empty-0 X-1 O-2.
	 * @param combi
	 * @param field
	 * @return
	 */
	private int getWinCombinationField(int combi, int field) {
		return this.gamesArea[Integer.parseInt(this.winCombinations[combi].substring(field, field + 1)) - 1];
	}

	/**
	 * 校验游戏是否结束.
	 * 
	 * @return
	 */
	private boolean checkForGameEnd() {
		int winner = this.checkFieldForWinner();
		if(winner > 0){
			// GAME ENDS HERE - we have a winner
			if(winner == this.userPlaying){
				this.myWindow.gameEnds(0);
			}else{
				this.myWindow.gameEnds(1);
			}
			return true;
		}else if(winner == -2){
			// GAME ENDS HERE - Tied
			this.myWindow.gameEnds(-1);
		}
		return false;
	}

	/**
	 * 校验是否有获胜者.
	 * @return
	 */
	private int checkFieldForWinner() {
		int checkSymbol = SYMBOL_X;
		for(int j = 0; j < 2; j++){
			for(int i = 0; i < this.winCombinations.length; i++){
				if(this.getWinCombinationField(i, 0) == checkSymbol
					&& this.getWinCombinationField(i, 1) == checkSymbol
					&& this.getWinCombinationField(i, 2) == checkSymbol){
					System.out.println("-------We have a winner!--------");
					this.lastWinCombi  = this.winCombinations[i];
					this.setGameStatus("The winner is: " + this.myWindow.symbols[checkSymbol]);
					this.gameEnds = true;
					return checkSymbol;
				}
			}
			checkSymbol = SYMBOL_O;
		}
		
		// No winner now - check for full game area
		for(int i = 0; i < this.gamesArea.length; i++){
			if(this.gamesArea[i] == EMPTY){
				return -1;
			}
		}
		
		// No empty field found - end game tied
		this.setGameStatus("Game is tied.");
		return -2;
	}

	/**
	 * 设置游戏进行状态.
	 * @param string
	 */
	private void setGameStatus(String status) {
		this.myWindow.setGameStatus(status);
	}

	/**
	 * 开始游戏.
	 * @param userBegins
	 * @param userSymbol
	 * @param enemyType
	 * @param aiQuality2
	 */
	public void startGame(boolean userBegins, int userSymbol, int enemyType, int aiQuality) {
		// TODO Auto-generated method stub
		System.out.println("----> in TTTGameLogic.startGame()");
		this.lastWinCombi = "";
		this.enemyType = enemyType;
		this.userPlaying = userSymbol;
		this.aiQuality = aiQuality;
		this.gameEnds = false;
		this.waittingForUser = userBegins;
		if(this.userPlaying == SYMBOL_X){
			this.enemyPlaying = SYMBOL_O;
		}else{
			this.enemyPlaying = SYMBOL_X;
		}
		for(int i = 1; i < 10; i++){
			this.gamesArea[i - 1] = EMPTY;
			this.myWindow.setSymbolOnButton(i, EMPTY);
		}
		if(this.enemyType == ENEMY_AI){
			System.out.println("AI quality: " + this.aiQuality);
		}
		// TODO
		if(userBegins){
			this.setGameStatus("Waiting for LOCAL...");
		}else{
			this.setGameStatus("Waiting for ENEMY...");
		}
		if(!this.waittingForUser && this.enemyType == ENEMY_AI){
			this.AITurn(true);
		}
	}

}
